#include <iostream>
#include <gtest/gtest.h>

extern "C" __declspec(dllimport) int getWords(char *fileName, char *word[], int *len);
extern "C" __declspec(dllimport) void outputRes(const char *path, int ans, char *result[], int len, bool useFile);
extern "C" __declspec(dllimport) int parse_para(int argc, char *argv[], int &cal_type, int &head, int &tail,
                                                int &banned, int &loop, char **path);

extern "C" __declspec(dllimport) int
gen_chain_word(char *words[], int len, char *result[], int head, int tail, int banned, int enable_loop);
extern "C" __declspec(dllimport) int gen_chains_all(char *words[], int len, char *result[]);
extern "C" __declspec(dllimport) int
gen_chain_char(char *words[], int len, char *result[], int head, int tail, int reject, int enable_loop);

extern "C" __declspec(dllimport) void solve(int argc, char *argv[]);

TEST(inputTest, getWords_1) {
    char name[100] = "..\\..\\inputs\\input0.txt";
    int len = 0;
    char *words[100];
    int r = getWords(name, words, &len);
    EXPECT_EQ(r, 0);
    EXPECT_EQ(len, 21);
}

TEST(inputTest, getWords_2) {
    char name[100] = "..\\..\\inputs\\input1.txt";
    int len = 0;
    char *words[100];
    int r = getWords(name, words, &len);
    EXPECT_EQ(r, 0);
    EXPECT_EQ(len, 13);
}

TEST(inputTest, getWords_3) {
    char name[100] = "..\\..\\inputs\\input12.txt";
    int len = 0;
    char *words[100];
    int r = getWords(name, words, &len);
    EXPECT_EQ(r, 0);
    EXPECT_EQ(len, 13);
}

TEST(inputTest, getWords_4) {
    char name[100] = "..\\..\\inputs\\input14.txt";
    int len = 0;
    char *words[100];
    int r = getWords(name, words, &len);
    EXPECT_EQ(r, 0);
    EXPECT_EQ(len, 0);
}

TEST(inputTest, getWords_5) {
    char name[100] = "..\\..\\inputs\\input14.ttt";
    int len = 0;
    char *words[100];
    int r = getWords(name, words, &len);
    EXPECT_EQ(r, -1);
}

TEST(inputTest, getWords_6) {
    char name[100] = "..\\..\\inputs\\input15.txt";
    int len = 0;
    char *words[100];
    int r = getWords(name, words, &len);
    EXPECT_EQ(r, 0);
    EXPECT_EQ(len, 4);
}

TEST(inputTest, parse_para_1) {
    char *path = nullptr;
    int len = 10;
    char *argv[15] = {" ", "-w", "input0.txt", "-h", "a", "-t", "b", "-j", "c", "-r"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);

    EXPECT_EQ(r, 0);
    EXPECT_EQ(cal_type, 2);
    EXPECT_EQ(head, 'a');
    EXPECT_EQ(tail, 'b');
    EXPECT_EQ(banned, 'c');
    EXPECT_EQ(loop, 1);
    std::cout << path << std::endl;
}

TEST(inputTest, parse_para_2) {
    char *path = nullptr;
    int len = 1;
    char *argv[10] = {""};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -1);
}

TEST(inputTest, parse_para_3) {
    char *path = nullptr;
    int len = 2;
    char *argv[10] = {"", "-n"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -7);
}

TEST(inputTest, parse_para_4) {
    char *path = nullptr;
    int len = 5;
    char *argv[10] = {"", "-n", "input.txt", "-w", "input.txt"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -9);
}

TEST(inputTest, parse_para_5) {
    char *path = nullptr;
    int len = 5;
    char *argv[10] = {"", "-c", "input.txt", "-w", "input.txt"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -2);
}

TEST(inputTest, parse_para_6) {
    char *path = nullptr;
    int len = 7;
    char *argv[10] = {"", "-c", "input.txt", "-h", "a", "-h", "a"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -3);
}

TEST(inputTest, parse_para_7) {
    char *path = nullptr;
    int len = 7;
    char *argv[10] = {"", "-c", "input.txt", "-t", "a", "-t", "a"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -3);
}

TEST(inputTest, parse_para_8) {
    char *path = nullptr;
    int len = 7;
    char *argv[10] = {"", "-c", "input.txt", "-j", "a", "-j", "a"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -3);
}

TEST(inputTest, parse_para_9) {
    char *path = nullptr;
    int len = 5;
    char *argv[10] = {"", "-c", "input.txt", "-r", "-r"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -3);
}

TEST(inputTest, parse_para_10) {
    char *path = nullptr;
    int len = 4;
    char *argv[10] = {"", "-c", "input.txt", "aa"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -4);
}

TEST(inputTest, parse_para_11) {
    char *path = nullptr;
    int len = 3;
    char *argv[10] = {"", "-c", "input.txp"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -5);
}

TEST(inputTest, parse_para_12) {
    char *path = nullptr;
    int len = 5;
    char *argv[10] = {"", "-c", "input.txt", "-h", "0"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -6);
}

TEST(inputTest, parse_para_13) {
    char *path = nullptr;
    int len = 5;
    char *argv[10] = {"", "-c", "input.txt", "-t", "0"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -6);
}

TEST(inputTest, parse_para_14) {
    char *path = nullptr;
    int len = 5;
    char *argv[10] = {"", "-c", "input.txt", "-j", "aa"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -6);
}

TEST(inputTest, parse_para_15) {
    char *path = nullptr;
    int len = 4;
    char *argv[10] = {"", "-c", "input.txt", "-h"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -8);
}

TEST(inputTest, parse_para_16) {
    char *path = nullptr;
    int len = 4;
    char *argv[10] = {"", "-c", "input.txt", "-t"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -8);
}

TEST(inputTest, parse_para_17) {
    char *path = nullptr;
    int len = 4;
    char *argv[10] = {"", "-c", "input.txt", "-j"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -8);
}

TEST(inputTest, parse_para_18) {
    char *path = nullptr;
    int len = 5;
    char *argv[10] = {"", "-w", "input.txt", "-c", "input.txt"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -2);
}

TEST(inputTest, parse_para_19) {
    char *path = nullptr;
    int len = 3;
    char *argv[10] = {"", "-n", "input.tpt"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -5);
}

TEST(inputTest, parse_para_20) {
    char *path = nullptr;
    int len = 2;
    char *argv[10] = {"", "-c"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -7);
}

TEST(inputTest, parse_para_21) {
    char *path = nullptr;
    int len = 2;
    char *argv[10] = {"", "-w"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -7);
}

TEST(inputTest, parse_para_22) {
    char *path = nullptr;
    int len = 3;
    char *argv[10] = {"", "-w", "input.pxt"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -5);
}

TEST(inputTest, parse_para_23) {
    char *path = nullptr;
    int len = 3;
    char *argv[10] = {"", "-p", "input"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -4);
}

TEST(inputTest, parse_para_24) {
    char *path = nullptr;
    int len = 3;
    char *argv[10] = {"", "-h", "i"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -1);
}

TEST(inputTest, parse_para_25) {
    char *path = nullptr;
    int len = 3;
    char *argv[10] = {"", "-n", "in"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);
    EXPECT_EQ(r, -5);
}

TEST(inputTest, parse_para_26) {
    char *path = nullptr;
    int len = 3;
    char *argv[15] = {" ", "-n", "input0.txt"};
    int cal_type = 0, head = 0, tail = 0, banned = 0, loop = 0;
    int r = parse_para(len, argv, cal_type, head, tail, banned, loop, &path);

    EXPECT_EQ(r, 0);
    EXPECT_EQ(cal_type, 1);
    EXPECT_EQ(head, 0);
    EXPECT_EQ(tail, 0);
    EXPECT_EQ(banned, 0);
    EXPECT_EQ(loop, 0);
    std::cout << path << std::endl;
}

//TEST(outputTest, outputRes_1) {
//    char *path = "C:\\Users\\25446\\Desktop\\untitled\\cmake-build-release\\bin";
//    char *results[20] = {"sdd", "sdsad", "hfgdf"};
//    int len = 3;
//    int res = 3;
//    int file = 1;
//    outputRes(path, res, results, len, file);
//}

//extern "C" __declspec(dllimport) int
//gen_chain_word(char *words[], int len, char *result[], int head, int tail, int banned, int enable_loop);
//extern "C" __declspec(dllimport) int gen_chains_all(char *words[], int len, char *result[]);
//extern "C" __declspec(dllimport) int
//gen_chain_char(char *words[], int len, char *result[], int head, int tail, int reject, int enable_loop);
//
//extern "C" __declspec(dllimport) void solve(int argc, char *argv[]);
TEST(coreTest, g_a_1) {
    char name[100] = "..\\..\\inputs\\input1.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int r1 = getWords(name, words, &len);
    int r2 = gen_chains_all(words, len, result);
    //outputRes("", r2, result, r2, 0);
    EXPECT_EQ(r2, -1);
}

TEST(coreTest, g_a_2) {
    char name[100] = "..\\..\\inputs\\input9.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int r1 = getWords(name, words, &len);
    int r2 = gen_chains_all(words, len, result);
    //outputRes("", r2, result, r2, 0);
    EXPECT_EQ(r2, 6);
}

TEST(coreTest, g_w_1) {
    char name[100] = "..\\..\\inputs\\input0.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int h = 0, t = 0, b = 0, r = 1;
    int r1 = getWords(name, words, &len);
    int r2 = gen_chain_word(words, len, result, h, t, b, r);
    EXPECT_EQ(r2, 14);
}

TEST(coreTest, g_w_2) {
    char name[100] = "..\\..\\inputs\\input0.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int h = 'p', t = 't', b = 'm', r = 1;
    int r1 = getWords(name, words, &len);
    int r2 = gen_chain_word(words, len, result, h, t, b, r);
    EXPECT_EQ(r2, -1);
}

TEST(coreTest, g_w_3) {
    char name[100] = "..\\..\\inputs\\input9.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int h = 'w', t = 0, b = 'q', r = 0;
    int r1 = getWords(name, words, &len);
    int r2 = gen_chain_word(words, len, result, h, t, b, r);
    EXPECT_EQ(r2, 4);
}
TEST(coreTest, g_c_1) {
    char name[100] = "..\\..\\inputs\\input0.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int h = 0, t = 0, b = 0, r = 1;
    int r1 = getWords(name, words, &len);
    int r2 = gen_chain_char(words, len, result, h, t, b, r);
    EXPECT_EQ(r2, 14);
}

TEST(coreTest, g_c_2) {
    char name[100] = "..\\..\\inputs\\input0.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int h = 'k', t = 'q', b = 'm', r = 1;
    int r1 = getWords(name, words, &len);
    int r2 = gen_chain_char(words, len, result, h, t, b, r);
    EXPECT_EQ(r2, 2);
}

TEST(coreTest, g_c_3) {
    char name[100] = "..\\..\\inputs\\input9.txt";
    int len = 0;
    char *words[100];
    char *result[100];
    int h = 'w', t = 0, b = 'q', r = 0;
    int r1 = getWords(name, words, &len);
    int r2 = gen_chain_char(words, len, result, h, t, b, r);
    EXPECT_EQ(r2, 14);
}

TEST(outputTest, outputRes_1) {
    char *path = "test.exe";
    char *results[20] = {"sdd", "sdsad", "hfgdf"};
    int len = 3;
    int res = 3;
    int file = 1;
    outputRes(path, res, results, len, file);
}

TEST(outputTest, outputRes_2) {
    char *path = ".\\test.exe";
    char *results[20] = {"sdd", "sdsad", "hfgdf"};
    int len = 3;
    int res = 3;
    int file = 1;
    outputRes(path, res, results, len, file);
}

TEST(outputTest, outputRes_3) {
    char *path = "./test.exe";
    char *results[20] = {"sdd", "sdsad", "hfgdf"};
    int len = 3;
    int res = 3;
    int file = 1;
    outputRes(path, res, results, len, file);
}

TEST(outputTest, outputRes_4) {
    char *path = "./test.exe";
    char *results[20] = {"sdd", "sdsad", "hfgdf"};
    int len = 3;
    int res = 3;
    int file = 0;
    outputRes(path, res, results, len, file);
}

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
